# Create your views here.
# !coding=utf-8

import cStringIO
import datetime
import os
import random
import re
import string

import django
from PIL import Image, ImageDraw, ImageFont
from django.http.response import HttpResponse
from rest_framework.response import Response
from rest_framework.views import APIView

from account.models import User
from response_content import *
from utils.date_scraper import get_today_stamp
from utils.decorators import need_super_user
from utils.ip import get_ip
from utils.response_content import ARGUMENT_ERRORS
from utils.shortcuts import http_400_response, http_200_response
from .models import AuthSMS
from .serializers import AuthSMSSer
from .sms import SMS

os.environ['DJANGO_SETTINGS_MODULE'] = 'backend.settings'
django.setup()


class AuthSMSView(APIView):
    def post(self, request, **kwargs):
        flag = request.data.get('flag')
        phone_number = request.data.get('phone_number')

        if not flag or not phone_number:
            return http_400_response(ARGUMENT_ERRORS)

        is_registered = User.objects.filter(phone_number=phone_number).exists()
        ip = get_ip(request)
        count = AuthSMS.objects.filter(ip=ip, send_time__gt=get_today_stamp()).count()
        if count >= 5:
            return http_400_response(TOO_MANY_REQUESTS)

        # 区分号码段
        # mobile = re.compile("^1(3[0-9]|4[57]|5[0-35-9]|8[0-9]|70)\\d{8}$")
        if len(phone_number) != 11:
            return http_400_response(PHONE_NUMBER_LESS_THAN_11)
        mobile = re.compile("^1\\d{10}$")
        res = mobile.match(phone_number)
        if res is None:
            return http_400_response(WRONG_PHONE_NUMBER_FORMAT)

        if flag == 'register' and is_registered:
            return http_400_response(PHONE_NUMBER_ALREADY_USER)
        elif flag == 'change_password' and (not is_registered):
            return http_400_response(PHONE_NUMBER_NOT_USER)
        elif flag == 'reset_password' and (not is_registered):
            return http_400_response(PHONE_NUMBER_NOT_USER)
        elif flag == 'change_phone_number' and is_registered:
            return http_400_response(PHONE_NUMBER_ALREADY_USER)
        elif flag == 'change_email' and (not is_registered):
            return http_400_response(PHONE_NUMBER_NOT_USER)
        elif flag not in ('register', 'change_password', 'reset_password',
                          'change_phone_number', 'change_email'):
            return http_400_response(WRONG_FLAG)

        dict_data = {
            'auth_code': str(_get_auth_code()),
            'phone_number': request.data.get('phone_number'),
            'ip': ip
        }

        ser = AuthSMSSer(data=dict_data)
        if ser.is_valid():
            auth_sms = ser.save()
            content_data = [auth_sms.auth_code, '5', '18888338198']
            res = send_auth_sms(phone_number, content_data)
            if res[0] is False:
                auth_sms.delete()
                return http_400_response(res[1])
        else:
            return http_400_response(ser.errors)
        return http_200_response(SEND_AUTH_SMS_OK)


def _get_auth_code():
    code = int(random.random() * 1000000)
    if code < 100000:
        return _get_auth_code()
    return code


def send_sms(phone_number, content):
    sms = SMS(phone_number, content, 160313)
    return sms.send()


def send_auth_sms(phone_number, content):
    sms = SMS(phone_number, content, 216144)
    return sms.send()


class ShowAuthCode(APIView):
    @need_super_user
    def get(self, request, **kwargs):
        auth_code = AuthSMS.objects.filter(phone_number=kwargs['pk'])
        return Response(AuthSMSSer(auth_code, many=True).data)


def expire_auth_code(code):
    code.content = "expired"
    code.save()


class VerifyAuthSMS(APIView):
    def post(self, request, **kwargs):
        auth_code = request.data['auth_code']
        phone_number = request.data['phone_number']
        try:
            auth_code = AuthSMS.objects.get(auth_code=auth_code, phone_number=phone_number)
        except AuthSMS.DoesNotExist:
            return http_400_response(WRONG_AUTH_SMS)
        auth_time = datetime.datetime.now()
        generate_time = datetime.datetime.fromtimestamp(auth_code.send_time)
        if (auth_time - generate_time).seconds > 300:
            auth_code.content = "expired"
            auth_code.save()
            return http_400_response(AUTH_SMS_EXPIRED)
        if auth_code.content == "expired":
            return http_400_response(AUTH_SMS_EXPIRED)
        return http_200_response(AUTH_SMS_OK)


class CaptchaView(APIView):
    def get(self, request, **kwargs):
        '''Captcha'''
        width = 100
        height = 50
        image = Image.new('RGB', (width, height), color=(255, 255, 255))  # model, size, background color
        font_file = os.path.join(os.path.dirname("/root/WisSky/sms/"), 'Arial.ttf')
        font = ImageFont.truetype(font_file, 36)
        # font = ImageFont.load_default().font
        draw = ImageDraw.Draw(image)
        for x in range(width):
            for y in range(height):
                draw.point((x, y), fill=rndColor())
        rand_str = ''.join(random.sample(string.letters + string.digits, 4))  # The random string
        draw.text((7, 0), rand_str, fill=rndColor2(), font=font)  # position, content, color, font
        del draw
        request.session['captcha'] = rand_str.lower()  # store the content in Django's session store
        buf = cStringIO.StringIO()  # a memory buffer used to store the generated image
        image.save(buf, 'jpeg')
        return HttpResponse(buf.getvalue(), 'image/jpeg')
        # return the image data stream as image/jpeg format, browser will treat it as an image


def rndColor():
    return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))


def rndColor2():
    return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))
